package com.itheima.project.adapter.impl;

import com.itheima.project.adapter.BasicPayAdapter;
import com.itheima.project.config.ShowApiConfig;
import com.itheima.project.constant.trade.TradingCacheConstant;
import com.itheima.project.constant.trade.TradingConstant;
import com.itheima.project.core.enums.trade.TradingEnum;
import com.itheima.project.exception.ProjectException;
import com.itheima.project.handler.BasicPayHandler;
import com.itheima.project.handler.NativePayHandler;
import com.itheima.project.service.ITradingService;
import com.itheima.project.utils.ExceptionsUtil;
import com.itheima.project.utils.RegisterBeanHandler;
import com.itheima.project.vo.trade.RefundRecordVo;
import com.itheima.project.vo.trade.TradingVo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName BasicPayAdapterImpl.java
 * @Description 基础交易适配
 */
@Slf4j
@Component
public class BasicPayAdapterImpl implements BasicPayAdapter {

    @Autowired
    ITradingService tradingService;

    @Autowired
    ShowApiConfig showApiConfig;

    @Autowired
    RegisterBeanHandler registerBeanHandler;

    @Autowired
    RedissonClient redissonClient;

    private static Map<String,String> basicPayHandlers =new HashMap<>();

    static {
        basicPayHandlers.put(TradingConstant.TRADING_CHANNEL_ALI_PAY,"aliBasicPayHandler");
        basicPayHandlers.put(TradingConstant.TRADING_CHANNEL_WECHAT_PAY,"wechatBasicPayHandler");
    }

    @Override
    public TradingVo queryTrading(TradingVo tradingVo) throws ProjectException {
        String basicPayHandlerString = basicPayHandlers.get(tradingVo.getTradingChannel());
        BasicPayHandler basicPayHandler = registerBeanHandler
                .getBean(basicPayHandlerString, BasicPayHandler.class);
        return basicPayHandler.queryTrading(tradingVo);
    }

    @Override
    public TradingVo refundTrading(TradingVo tradingVo) throws ProjectException {
        //1、对交易订单加锁
        Long productOrderNo = tradingVo.getProductOrderNo();
        String key = TradingCacheConstant.REFUND_PAY + productOrderNo;
        RLock lock = redissonClient.getFairLock(key);
        try {
            boolean flag = lock.tryLock(TradingCacheConstant.REDIS_WAIT_TIME, TimeUnit.SECONDS);
            if (flag){
                //2、统一收单交易退款接口
                String basicPayHandlerString = basicPayHandlers.get(tradingVo.getTradingChannel());
                BasicPayHandler basicPayHandler = registerBeanHandler
                        .getBean(basicPayHandlerString, BasicPayHandler.class);
                return basicPayHandler.refundTrading(tradingVo);
            }else {
                throw new ProjectException(TradingEnum.NATIVE_REFUND_FAIL);
            }
        } catch (Exception e) {
            log.error("统一收单交易退款接口异常:{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(TradingEnum.NATIVE_REFUND_FAIL);
        }finally {
            lock.unlock();
        }
    }

    @Override
    public void queryRefundTrading(RefundRecordVo refundRecordVo) throws ProjectException {
        String basicPayHandlerString = basicPayHandlers.get(refundRecordVo.getTradingChannel());
        BasicPayHandler basicPayHandler = registerBeanHandler
                .getBean(basicPayHandlerString, BasicPayHandler.class);
        basicPayHandler.queryRefundTrading(refundRecordVo);
    }

}
